
#ifndef __SPARROW_H__
#define __SPARROW_H__

#define NULL ((void *)0)

typedef unsigned char  uint8_t;
typedef unsigned int   uint32_t;
typedef unsigned short uint16_t;

typedef signed char  int8_t;
typedef signed int   int32_t;
typedef signed short int16_t;

//板子上集成的LED地址，一共4个，分别对应0 - 3 位
#define LED_A (*(volatile uint32_t *)0x80000000)

//板子上集成的按键开关，一共3个
#define KEY   (*(volatile uint32_t *)0x80000004)

//第一个外接LED的地址，一共8个LED，分别对应bit 0 - 7
#define LED_B (*(volatile uint32_t *)0x80000008)

//第一个外接DIP的地址，一共8个DIP，分别对应bit 0 - 7
#define DIP_B (*(volatile uint32_t *)0x8000000c)

#define UART_TX_REG (*(volatile uint32_t *)0x80000010)
#define UART_RX_REG (*(volatile uint32_t *)0x80000014)
#define UART_STATUS (*(volatile uint32_t *)0x80000018)

//第二个外接LED的地址，一共8个LED，分别对应bit 0 - 7
#define LED_C (*(volatile uint32_t *)0x8000001c)

//第二个外接DIP的地址，一共8个DIP，分别对应bit 0 - 7
#define DIP_C (*(volatile uint32_t *)0x80000020)

//七段数码管的地址，直接向这些地址写入16进制的整数0 - f，
//就可以在数码管上显示出来
#define SSD_0 (*(volatile uint32_t *)0x80000024)
#define SSD_1 (*(volatile uint32_t *)0x80000028)
#define SSD_2 (*(volatile uint32_t *)0x8000002c)
#define SSD_3 (*(volatile uint32_t *)0x80000030)

//OLED显示屏的I2C总线的GPIO引脚地址
#define OLED_SCL   ((volatile uint32_t *)0x80000040)
#define OLED_SDA   ((volatile uint32_t *)0x80000044)

#define TIMER   (*(volatile uint32_t *)0x80000048)

inline uint32_t spr_get_ms(void)
{
    return TIMER;
}


//UART的状态寄存器每个位的意义
#define UART_ST_TX_FULL  (1<<0)
#define UART_ST_TX_EMPTY (1<<1)
#define UART_ST_RX_FULL  (1<<2)
#define UART_ST_RX_EMPTY (1<<3)

//防止编译器把空循环代码优化掉的宏
#define barrier()  __asm__ volatile ("" ::: "memory");     

void spr_delay(unsigned int moments);
void spr_err(char *msg);
uint32_t spr_printf(char *fmt, ...);
void spr_puts(char *msg);
int spr_get_ch(void);
uint32_t spr_get_dip_b(void);
uint32_t spr_get_dip_c(void);

void spr_srand(uint32_t seed);
uint32_t spr_rand(void);


typedef unsigned char *va_list;

// 参数对齐（按指针大小对齐）
#define _ALIGN_SIZE(n) \
    (((sizeof(n) + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*))

// 初始化参数指针
#define va_start(ap, last_arg) \
    (ap = ((va_list)&(last_arg) + _ALIGN_SIZE(last_arg)))

// 获取下一个参数
#define va_arg(ap, type)                              \
    (*(type *)((ap += _ALIGN_SIZE(type)) - _ALIGN_SIZE(type)))

// 结束参数获取
#define va_end(ap) ((void)(ap = (va_list)0))

#endif //__SPARROW_H__

